package cn.xs.order.action;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import javax.annotation.Resource;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONObject;

import org.apache.struts2.ServletActionContext;
import org.apache.struts2.interceptor.SessionAware;

import cn.xs.core.util.PaymentUtil;
import cn.xs.order.entity.Car;
import cn.xs.order.entity.CarItem;
import cn.xs.order.entity.Order;
import cn.xs.order.entity.OrderItem;
import cn.xs.order.service.OrderService;
import cn.xs.user.entity.User;

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

/**
 * 订单和购物车控制器
 * @author xs
 *
 */
public class OrderAction extends ActionSupport implements SessionAware{

	@Resource
	private OrderService orderService;
	
	private Order order;
	private List<Order> orderList;
	
	private String deleteId;
	
	/**
	 * 跳转到我的购物车页面
	 * @return
	 */
	public String toMyCarUI(){
		return "mycarUI";
	}

	/**
	 * 跳转到我的订单页面
	 * @return
	 */
	public String toMyOrderUI(){
		User userInfo = (User)session.get("USER_INFO");
		orderList = orderService.findOrdersByUserId(userInfo.getId());
		return "myorderUI";
	}
	
	
	/**
	 * 跳转到订单详细页面
	 */
	public String toDetailUI(){
		if(order!=null && order.getId()!=null){
			order = orderService.find(order.getId());
		}
		return "detailUI";
	}
	/**
	 * 生成订单
	 * 		1.取session,Car,sumprice,CarNumber,userinfo(当前用户)
	 * 		2.生成Order,遍历Car同时生成orderItem,完善order并保存
	 * 		3.初始化session中的购物车
	 */
	public String addOrder(){
		if(order!=null){
			//1
			Car car = (Car) session.get("Car");
			User userInfo = car.getUser();
			
			//2
			order.setId(car.getId());
			order.setTime(new Timestamp(System.currentTimeMillis()));
			order.setSumPrice(car.getSumprice());
			order.setUser_id(userInfo.getId());
			//..do some thing
			order.setStatus(Order.order_nopay);
			List<OrderItem> orderItems = new ArrayList<OrderItem>();
			//遍历
			for(CarItem item : car.getItems()){
				OrderItem o = new OrderItem(item, order);
				orderItems.add(o);
			}
			order.setOrderItems(orderItems);
			orderService.save(order);
			
			//3初始化购物车
			session.remove("Car");
			ActionContext.getContext().put("sumPrice", order.getSumPrice());
			ActionContext.getContext().put("id", order.getId());
			
		}
		//4
		return "pay";
	}
	/**
	 * 跳转到支付页面去
	 * @return
	 */
	public String pay(){
		if(order!=null){
			order = orderService.find(order.getId());
			ActionContext.getContext().put("sumPrice", order.getSumPrice());
			ActionContext.getContext().put("id", order.getId());
		}
		return "pay";
	}
	/**
	 * 进行支付处理
	 * @throws ServletException
	 * @throws IOException
	 */
	public void payment()
			throws ServletException, IOException {
		/*
		 * 1. 准备访问易宝网关的数据
		 */
		Properties props = new Properties();
		props.load(this.getClass().getClassLoader()
				.getResourceAsStream("payment.properties"));
		HttpServletRequest req = ServletActionContext.getRequest();
		HttpServletResponse resp = ServletActionContext.getResponse();
		
		String p0_Cmd = "Buy";// 业务类型
		String p1_MerId = props.getProperty("p1_MerId");// 商户编号，从配置文件上加载
		String p2_Order = req.getParameter("oid");// 商户订单号
//		String p3_Amt = req.getParameter("oid");// 支付金额
		String p3_Amt = "0.01";// 支付金额	//只能做模拟支付功能放0.01元
		String p4_Cur = "CNY";// 交易币种
		String p5_Pid = "";// 商品名称
		String p6_Pcat = "";// 商品种类
		String p7_Pdesc = "";// 商品描述
		String p8_Url = props.getProperty("p8_Url");// 商户接收支付成功数据的地址，从配置文件上加载
		String p9_SAF = "";// 送货地址
		String pa_MP = "";// 商户扩展信息
		String pd_FrpId = req.getParameter("yh");// 支付通道编码
		String pr_NeedResponse = "1";// 应答机制
		
		// 使用密钥生成hmac，它是不可逆的
		String keyValue = props.getProperty("keyValue");// 密钥，从配置文件上加载
		String hmac = PaymentUtil.buildHmac(p0_Cmd, p1_MerId, p2_Order, p3_Amt,
				p4_Cur, p5_Pid, p6_Pcat, p7_Pdesc, p8_Url, p9_SAF, pa_MP,
				pd_FrpId, pr_NeedResponse, keyValue);
		
		/* 
		 * 把数据保存到request中，
		 * 转发到/WEB-INF/jsp/sendpay.jsp页面，
		 * 这个页面会把数据显示在表单中，表单会自动提交到易宝网关。
		 */
		StringBuffer sb = new StringBuffer();
		sb.append("https://www.yeepay.com/app-merchant-proxy/node?");
		sb.append("p0_Cmd="+p0_Cmd);
		sb.append("&p1_MerId="+ p1_MerId);
		sb.append("&p2_Order="+ p2_Order);
		sb.append("&p3_Amt="+p3_Amt);
		sb.append("&p4_Cur="+p4_Cur);
		sb.append("&p5_Pid="+p5_Pid);
		sb.append("&p6_Pcat="+ p6_Pcat);
		sb.append("&p7_Pdesc="+ p7_Pdesc);
		sb.append("&p8_Url="+ p8_Url);
		sb.append("&p9_SAF="+p9_SAF);
		sb.append("&pa_MP="+ pa_MP);
		sb.append("&pd_FrpId="+ pd_FrpId);
		sb.append("&pr_NeedResponse="+ pr_NeedResponse);
		sb.append("&hmac="+ hmac);
		
		resp.sendRedirect(sb.toString());
	}
	
	/**
	 * 支付成功后回调函数进行校验
	 * 然后跳转支付成功消息页面
	 * @param req
	 * @param resp
	 * @return
	 * @throws ServletException
	 * @throws IOException
	 */
	public String back()
			throws ServletException, IOException {
		HttpServletRequest req = ServletActionContext.getRequest();
		String p1_MerId = req.getParameter("p1_MerId");//商户编号
		String r0_Cmd = req.getParameter("r0_Cmd");// 业务类型
		String r1_Code = req.getParameter("r1_Code");//支付结果
		String r2_TrxId = req.getParameter("r2_TrxId");//易宝支付交易流水号
		String r3_Amt = req.getParameter("r3_Amt");//支付金额
		String r4_Cur = req.getParameter("r4_Cur");//交易币种
		String r5_Pid = req.getParameter("r5_Pid");// 商品名称
		String r6_Order = req.getParameter("r6_Order");//商户订单号
		String r7_Uid = req.getParameter("r7_Uid");//易宝支付会员ID
		String r8_MP = req.getParameter("r8_MP");//商户扩展信息
		String r9_BType = req.getParameter("r9_BType");//交易结果返回类型
		String hmac = req.getParameter("hmac");//签名数据
		
		// 校验签名是否有效
		Properties props = new Properties();
		props.load(this.getClass().getClassLoader()
				.getResourceAsStream("payment.properties"));
		String keyValue = props.getProperty("keyValue");// 密钥，从配置文件上加载
		
		boolean flag = PaymentUtil.verifyCallback(hmac, p1_MerId, r0_Cmd, 
				r1_Code, r2_TrxId, r3_Amt, r4_Cur, r5_Pid, r6_Order, 
				r7_Uid, r8_MP, r9_BType, keyValue);
		if(flag) {
			if("1".equals(r1_Code)) {
				orderService.setOrderStatus(r6_Order, Order.order_waitdeliver);
				req.setAttribute("code", "success");
				req.setAttribute("msg", "支付成功！");
			} else {
				req.setAttribute("code", "error");
				req.setAttribute("msg", "支付失败，不知道因为为啥！");			
			}
		} else {
			System.out.println("无效的签名");
			req.setAttribute("code", "error");
			req.setAttribute("msg", "支付失败，无效的签名！");
		}
		
		//直接跳转到订单成功消息页面
		return "ordermsg";
	}
	
	
	/**
	 * 异步删除购物项
	 * 		1.拿到购物车,找出里面对应的购物项,删除
	 * 		2.修改购物车里面的数量
	 */
	public void deleteCarItem(){
		if(deleteId!=null){
			Car car = (Car) session.get("Car"); 
			Integer carNumber = car.getCarNumber();
			Double sumPrice = car.getSumprice();
			List<CarItem> items = car.getItems();
			for(int i =0;i<items.size();i++){
				if(items.get(i).getId().equals(deleteId)){
					int num = items.get(i).getQuantity();
					carNumber -= num;
					sumPrice -=items.get(i).getPrice();
					car.setCarNumber(carNumber);
					car.setSumprice(sumPrice);
					items.remove(i);
					break;
				}
			}
			
			try {
				JSONObject result = new JSONObject();
				result.put("msg", "success");
				result.put("sumPrice", car.getSumprice());
				result.put("carNumber", car.getCarNumber());
				HttpServletResponse response = ServletActionContext.getResponse();
				response.setContentType("text/html;charset=utf-8");
				PrintWriter out = response.getWriter();
				out.print(result.toString());
				out.flush();
				out.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
			
		}
	}
	
	/**
	 * 用户确认收货,改变订单状态为'已签收',重定向Action到我的订单页面去
	 * @return
	 */
	public String doGain(){
		if(order!=null && order.getId()!=null){
			orderService.setOrderStatus(order.getId(), Order.order_sign);
		}
		return "myorderUIr";
	}
	public String getDeleteId() {
		return deleteId;
	}
	public void setDeleteId(String deleteId) {
		this.deleteId = deleteId;
	}
	public Order getOrder() {
		return order;
	}
	public void setOrder(Order order) {
		this.order = order;
	}
	public List<Order> getOrderList() {
		return orderList;
	}
	public void setOrderList(List<Order> orderList) {
		this.orderList = orderList;
	}

	//意识注入session
	Map<String, Object> session;
	public void setSession(Map<String, Object> session) {
		this.session = session;
	}
	
}
